import type {App} from 'vue';
import {defineAsyncComponent} from 'vue';
import * as ElementPlusIconsVue from '@element-plus/icons-vue';
import router from '/@/router/index';
import {storeToRefs} from 'pinia';
import {verifyUrl} from '/@/utils/toolsValidate';
import stores from "/@/stores";
import {CacheManager} from "/@/cache";

// 引入组件
const SvgIcon = defineAsyncComponent(() => import('/@/components/svgIcon/index.vue'));


/**
 * 统一批量导出
 * @method elSvg 导出全局注册 element plus svg 图标
 * @method useTitle 设置浏览器标题国际化
 * @method setTagsViewNameI18n 设置 自定义 tagsView 名称、 自定义 tagsView 名称国际化
 * @method lazyImg 图片懒加载
 * @method globalComponentSize() element plus 全局组件大小
 * @method deepClone 对象深克隆
 * @method isMobile 判断是否是移动端
 * @method handleEmpty 判断数组对象中所有属性是否为空，为空则删除当前行对象
 */
const other = {
    /**
     * 导出全局注册 element plus svg 图标
     * @param app vue 实例
     * @description 使用：https://element-plus.gitee.io/zh-CN/component/icon.html
     */
    elSvg: (app: App) => {
        for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
            app.component("ele-" + key, component)
        }
        app.component('SvgIcon', SvgIcon);

    },
    /**
     * 设置 自定义 tagsView 名称
     * @param route 路由 query、params 中的 tagsViewName
     * @returns 返回当前 tagsViewName 名称
     */
    setTagsViewNameI18n(route: RouteToFrom) {
        let tagsViewName: string = '';
        const {query, params, meta} = route;
        if (query?.tagsViewName || params?.tagsViewName) {
            // 非国际化
            tagsViewName = query?.tagsViewName || params?.tagsViewName;
        } else {
            // 非自定义 tagsView 名称
            tagsViewName = meta?.title || tagsViewName;
        }
        return tagsViewName;
    },


    /**
     * 全局组件大小
     * @returns 返回 `window.localStorage` 中读取的缓存值 `globalComponentSize`
     */
    globalComponentSize: (): "large" | "default" | "small" => {
        const {themeConfig} = storeToRefs(stores.themeConfigState);
        return CacheManager.getThemeConfig()?.globalComponentSize || themeConfig.value?.globalComponentSize || "default";
    },

    /**
     * 对象深克隆工具方法（支持解决循环引用，嵌套对象也进行克隆）
     * @param obj 要克隆的对象
     * @param clonedMap 用于记录已经克隆的对象的 Map
     * @returns 克隆后的新对象
     */
    deepClone: function deepClone<T = any>(obj: T, clonedMap = new Map<any, any>()): T {
        if (clonedMap.has(obj)) { // 如果已经存在该对象，则直接返回已有的克隆对象
            return clonedMap.get(obj);
        }
        if (obj === null || typeof obj !== 'object' || obj instanceof Date || obj instanceof RegExp) { // 如果是原始类型、日期类型或正则表达式，则直接返回
            return obj;
        }
        const result: any = Array.isArray(obj) ? [] : {};
        clonedMap.set(obj, result); // 将原对象和克隆后的对象存入 Map 中
        for (const key in obj) {
            if (Object.prototype.hasOwnProperty.call(obj, key)) { // 遍历自身属性，不遍历原型链上的属性
                let value = obj[key];
                result[key] = deepClone(value, clonedMap); // 递归复制属性
            }
        }
        return result;
    },
    /**
     * 判断是否是移动端
     */
    isMobile: (): boolean => {
        return !!navigator.userAgent.match(
            /('phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone')/i
        );
    }, /**
     * 打开外部链接
     * @param val 当前点击项菜单
     */
    handleOpenLink: (val: RouteItem) => {
        const {origin, pathname} = window.location;
        router.push(val.path);
        if (verifyUrl(<string>val.meta?.isLink)) window.open(val.meta?.isLink);
        else window.open(`${origin}${pathname}#${val.meta?.isLink}`);
    },
};

// 统一批量导出
export default other;
